package service

import (
	"database/sql"
	"encoding/json"
	"errors"
	"haiqiu-go-admin/dao"
	"haiqiu-go-admin/entity"
	"haiqiu-go-admin/entity/dto"
	"haiqiu-go-admin/entity/vo"
	"haiqiu-go-admin/result"
	"haiqiu-go-admin/utils"
	"log"
	"net/http"
	"strconv"
	"time"
)

// RoleById 根据ID查询数据
func RoleById(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson := utils.GetParamsFormatJson(w, r)
	roleIdStr := formatJson["id"][0]
	roleId, err := strconv.ParseInt(roleIdStr, 10, 64)
	if err != nil {
		panic(err)
		return nil, err
	}
	role, err := dao.RoleById(roleId)
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// RolePage 分页查询
func RolePage(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson, err := utils.GetBodyFormatJson(w, r)
	if err != nil {
		return nil, errors.New(result.ParamsErr)
	}
	var page = dto.RoleQueryDto{}
	err = json.Unmarshal(formatJson, &page)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	count := dao.RolePageCount(&page)
	if count == 0 {
		return vo.PageData{Total: 0}, nil
	}
	var pageData vo.PageData
	list, err := dao.RolePageList(&page)
	pageData.Data = list
	pageData.Total = count
	pageData.PageIndex = page.PageIndex
	pageData.PageSize = page.PageSize
	if err != nil {
		return nil, err
	}
	return pageData, nil
}

// RoleAdd 新增数据
func RoleAdd(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson, err := utils.GetBodyFormatJson(w, r)
	if err != nil {
		return nil, err
	}
	var sysRole = entity.SysRole{}
	err = json.Unmarshal(formatJson, &sysRole)
	var roleDto = dto.RoleDto{}
	err = json.Unmarshal(formatJson, &roleDto)
	if err != nil {
		return nil, err
	}
	var nowTime = time.Now()
	sysRole.CreateTime = &nowTime
	sysRole.UpdateTime = &nowTime
	//事务处理
	tx, err := dao.DB.Begin()
	defer func() {
		if (err != nil || recover() != nil) && tx != nil {
			log.Println("触发事务撤销")
			if err := tx.Rollback(); err != nil {
				log.Println(err.Error())
			}
		}
	}()
	lastInsertId, err := dao.RoleAdd(&sysRole, tx)
	if err != nil {
		return nil, err
	}
	roleDto.Id = lastInsertId
	err = addRoleAssociation(&roleDto, tx)
	if err != nil {
		return nil, err
	}
	//提交事务
	err = tx.Commit()
	if err != nil {
		return nil, err
	}
	return lastInsertId, nil
}

// RoleUpdate 根据ID更新数据
func RoleUpdate(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson, err := utils.GetBodyFormatJson(w, r)
	if err != nil {
		return nil, err
	}
	var sysRole = entity.SysRole{}
	err = json.Unmarshal(formatJson, &sysRole)
	var roleDto = dto.RoleDto{}
	err = json.Unmarshal(formatJson, &roleDto)
	if err != nil {
		return nil, err
	}
	var nowTime = time.Now()
	sysRole.UpdateTime = &nowTime
	//事务处理
	tx, err := dao.DB.Begin()
	defer func() {
		if (err != nil || recover() != nil) && tx != nil {
			log.Println(result.Transaction)
			if err := tx.Rollback(); err != nil {
				log.Println(err.Error())
			}
		}
	}()
	rowsAffected, err := dao.RoleUpdate(&sysRole, tx)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	err = addRoleAssociation(&roleDto, tx)
	if err != nil {
		panic(err)
		return nil, err
	}
	//提交事务
	err = tx.Commit()
	if err != nil {
		panic(err)
		return nil, err
	}
	return rowsAffected, nil
}

// 添加角色关联关系
func addRoleAssociation(roleDto *dto.RoleDto, tx *sql.Tx) error {
	if len(roleDto.MenuIds) != 0 {
		err := dao.DeleteMenuByRoleId(roleDto.Id, tx)
		if err != nil {
			return err
		}
		err = dao.AddMenuByRoleId(roleDto.Id, roleDto.MenuIds, tx)
		if err != nil {
			return err
		}
	}
	return nil
}

// RoleDeleteBatch 批量删除数据
func RoleDeleteBatch(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson, err := utils.GetBodyFormatJson(w, r)
	if err != nil {
		return nil, err
	}
	var ids []int64
	err = json.Unmarshal(formatJson, &ids)
	if err != nil {
		return nil, err
	}

	add, err := dao.RoleDeleteBatch(ids)
	if err != nil {
		return nil, err
	}
	return add, nil
}

// RoleList 查询所有数据
func RoleList(w http.ResponseWriter, r *http.Request) (*[]entity.SysRole, error) {
	roleList, err := dao.RoleList()
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	return roleList, nil
}

func ActiveRole(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson, err := utils.GetBodyFormatJson(w, r)
	if err != nil {
		log.Println(err.Error())
		panic(err)
		return nil, err
	}
	var sysRoles []entity.SysRole
	err = json.Unmarshal(formatJson, &sysRoles)
	if err != nil {
		log.Println(err.Error())
		panic(err)
		return nil, err
	}
	rowsAffected, err := dao.ActiveRoleById(sysRoles)
	return rowsAffected, err
}

// 根据角色ID查询角色已授权用户列表
func AllocatedList(w http.ResponseWriter, r *http.Request) (any, error) {
	err, allocatedDto := getUrlParams(w, r)
	if err != nil {
		return nil, err
	}

	count, err := dao.AllocatedCount(&allocatedDto)
	if err != nil {
		log.Println(err.Error())
		panic(err)
		return nil, err
	}
	users, err := dao.AllocatedPage(&allocatedDto)
	if err != nil {
		log.Println(err.Error())
		panic(err)
		return nil, err
	}
	mapData := make(map[string]any)
	mapData["rows"] = users
	mapData["count"] = count
	return mapData, nil
}

// 根据角色ID查询角色未授权用户列表
func UnallocatedList(w http.ResponseWriter, r *http.Request) (any, error) {
	err, allocatedDto := getUrlParams(w, r)
	if err != nil {
		return nil, err
	}

	count, err := dao.UnAllocatedCount(&allocatedDto)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	users, err := dao.UnAllocatedPage(&allocatedDto)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	mapData := make(map[string]any)
	mapData["rows"] = users
	mapData["count"] = count
	return mapData, nil
}

func getUrlParams(w http.ResponseWriter, r *http.Request) (error, dto.AllocatedDto) {
	formatJson := utils.GetParamsFormatJson(w, r)

	pageIndex, err := strconv.ParseInt(formatJson["pageIndex"][0], 10, 64)
	if err != nil {
		log.Println(err.Error())
		return err, dto.AllocatedDto{}
	}
	pageSize, err := strconv.ParseInt(formatJson["pageSize"][0], 10, 64)
	if err != nil {
		log.Println(err.Error())
		return err, dto.AllocatedDto{}
	}
	roleId, err := strconv.ParseInt(formatJson["roleId"][0], 10, 64)
	if err != nil {
		log.Println(err.Error())
		return err, dto.AllocatedDto{}
	}
	var allocatedDto dto.AllocatedDto

	allocatedDto.PageIndex = pageIndex
	allocatedDto.PageSize = pageSize
	allocatedDto.RoleId = &roleId
	if formatJson["username"] != nil {
		allocatedDto.Username = &formatJson["username"][0]
	}
	if formatJson["phone"] != nil {
		allocatedDto.Phone = &formatJson["phone"][0]
	}
	if formatJson["email"] != nil {
		allocatedDto.Email = &formatJson["email"][0]
	}
	return nil, allocatedDto
}

func Authorize(w http.ResponseWriter, r *http.Request) (any, error) {
	formatJson, err := utils.GetBodyFormatJson(w, r)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	var roleAuthorize dto.RoleAuthorize
	err = json.Unmarshal(formatJson, &roleAuthorize)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	roleId, err := strconv.ParseInt(roleAuthorize.RoleId, 10, 64)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	if roleAuthorize.Active {
		// 批量激活
		_, err = dao.UserAddByRoleId(roleId, roleAuthorize.UserIds)

	} else {
		// 批量删除
		_, err = dao.UserRemoveByRoleId(roleId, roleAuthorize.UserIds)
	}
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	return nil, err
}
